import logging
import mimetypes
import os
from django.http import StreamingHttpResponse
from rest_framework.viewsets import ModelViewSet
from rest_framework.exceptions import ValidationError
from public.utils import generate_file_stream
from rest_framework.response import Response
from rest_framework.decorators import action
from . import models
from . import serializers
# Create your views here.


class DownloadFileAPIView(ModelViewSet):
    serializer_class = serializers.DownloadListSerializer
    queryset = []

    def list(self, request, *args, **kwargs):
        filter_type = kwargs['filter_type']
        data_queryset = []

        def filter_by_search(queryset):
            return queryset.filter(name__icontains=request.query_params.get('search', ""))
        if filter_type == "bacteria":
            data_queryset = models.BacteriaModel.objects.all()
            data_queryset = filter_by_search(data_queryset)
        elif filter_type == "phage":
            data_queryset = models.PhageModel.objects.all()
            data_queryset = filter_by_search(data_queryset)
        elif filter_type == "prophage":
            data_queryset = models.ProPhageModel.objects.all()
            data_queryset = filter_by_search(data_queryset)
        elif filter_type == "all":
            data_queryset = models.AllDownloadModel.objects.all()
            data_queryset = filter_by_search(data_queryset)

        queryset = self.filter_queryset(data_queryset)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=['get'])
    def exists(self, request, *args, **kwargs):
        pk = kwargs["pk"]
        filter_type = kwargs['filter_type']
        if filter_type == "bacteria":
            data_queryset = models.BacteriaModel.objects.filter(pk=pk)
        elif filter_type == "phage":
            data_queryset = models.PhageModel.objects.filter(pk=pk)
        elif filter_type == "prophage":
            data_queryset = models.ProPhageModel.objects.filter(pk=pk)
        elif filter_type == "all":
            data_queryset = models.AllDownloadModel.objects.filter(pk=pk)

        if not len(data_queryset):
            raise ValidationError({"message": "请传入正确的文件 id"})

        data: models.PhageModel = data_queryset[0]
        file_path = data.path
        if not os.path.exists(file_path):
            logging.error(f'File where in {file_path} not exists')
            raise ValidationError({"message": "该文件不存在"})
        if os.path.isdir(file_path):
            raise ValidationError({"message": "路径指向了一个目录"})

        return Response({"message": "获取文件成功"})

    @action(detail=True, methods=['get'])
    def download(self, request, *args, **kwargs):
        pk = kwargs["pk"]
        filter_type = kwargs['filter_type']
        if filter_type == "bacteria":
            data_queryset = models.BacteriaModel.objects.filter(pk=pk)
        elif filter_type == "phage":
            data_queryset = models.PhageModel.objects.filter(pk=pk)
        elif filter_type == "prophage":
            data_queryset = models.ProPhageModel.objects.filter(pk=pk)
        elif filter_type == "all":
            data_queryset = models.AllDownloadModel.objects.filter(pk=pk)

        if not len(data_queryset):
            raise ValidationError({"message": "请传入正确的文件 id"})

        data: models.PhageModel = data_queryset[0]
        filenames = data.path.split("/")
        filename = filenames[len(filenames)-1]
        file_path = data.path
        if not os.path.exists(file_path):
            logging.error(f'File where in {file_path} not exists')
            raise ValidationError({"message": "该文件不存在"})
        if os.path.isdir(file_path):
            raise ValidationError({"message": "路径指向了一个目录"})

        response = StreamingHttpResponse(
            generate_file_stream(file_path=file_path))
        response.headers["filename"] = filename
        response.headers['Content-Disposition'] = "attachment; filename="+filename
        response.headers['Content-Type'] = mimetypes.guess_type(
            filename)[0] or 'application/octet-stream'
        response['Access-Control-Expose-Headers'] = 'filename'
        return response

    @action(detail=False, methods=['get'])
    def file(self, request, *args, **kwargs):
        filename = "results.zip"
        file_path = request.query_params["file_path"]

        response = StreamingHttpResponse(
            generate_file_stream(file_path=file_path))
        response.headers["filename"] = filename
        response.headers['Content-Disposition'] = "attachment; filename="+filename
        response.headers['Content-Type'] = mimetypes.guess_type(
            filename)[0] or 'application/octet-stream'
        response['Access-Control-Expose-Headers'] = 'filename'
        return response

    @action(detail=False, methods=['get'])
    def file_exists(self, request, *args, **kwargs):
        file_path = request.query_params["file_path"]
        if not os.path.exists(file_path):
            logging.error(f'File where in {file_path} not exists')
            raise ValidationError({"message": "该文件不存在"})
        if os.path.isdir(file_path):
            raise ValidationError({"message": "路径指向了一个目录"})

        return Response({"message": "获取文件成功"})

    @action(detail=False, methods=['get'])
    def static_ids(self, request, *args, **kwargs):
        data_queryset = []
        data = {}

        data_queryset = models.BacteriaModel.objects.all()
        serializer = self.get_serializer(data_queryset, many=True)
        data["bacterial"] = serializer.data
        data_queryset = models.PhageModel.objects.all()
        serializer = self.get_serializer(data_queryset, many=True)
        data["phage"] = serializer.data

        data_queryset = models.ProPhageModel.objects.all()
        serializer = self.get_serializer(data_queryset, many=True)
        data["prophage"] = serializer.data
        data_queryset = models.AllDownloadModel.objects.all()
        serializer = self.get_serializer(data_queryset, many=True)
        data["all"] = serializer.data

        return Response(data)

    @action(detail=False, methods=['get'])
    def static(self, request, *args, **kwargs):
        base_path = "/home/web/web_app/structure"
        filename = request.query_params["filename"]

        file_path = f'{base_path}/web_static/help/{filename}'

        if not os.path.exists(file_path):
            logging.error(f'File where in {file_path} not exists')
            raise ValidationError({"message": "该文件不存在"})
        if os.path.isdir(file_path):
            raise ValidationError({"message": "路径指向了一个目录"})

        response = StreamingHttpResponse(
            generate_file_stream(file_path=file_path))
        response.headers["filename"] = filename
        response.headers['Content-Disposition'] = "attachment; filename="+filename
        response.headers['Content-Type'] = mimetypes.guess_type(
            filename)[0] or 'application/octet-stream'
        response['Access-Control-Expose-Headers'] = 'filename'
        return response
